<?php
/**
 * A thread interface
 *
 * This file is allowed to only access a db.interface if neccesary
 * and itself. 
 *
 **/
  

// XXX : turn off error through when not debugging
// XXX : the set methods need input validation for SQL inj.
session_start();

require_once 'db.php';

/** UTIL FNS **/

// TODO
function clean( $string ) {
  return ($string);
}

function openDbConn() {
  global $db_name, $db_user, $db_pass, $db_options; 
  return new PDO($db_name, $db_user, $db_pass, $db_options);
  $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
}

/** ACCESS FNS **/

// int -> int -> obj?
function getPosts($threadNum, $start, $inc) {
  try {
    $db = openDbConn();
    return $db->query("SELECT post.name, post.datum, post.rank, post.date, post.tid, user.name AS uname
                         FROM post
                           LEFT JOIN user
                             ON post.uid = user.uid
                           WHERE post.tid = $threadNum 
                             AND post.rank
                         ORDER BY rank
                         LIMIT $start, $inc;");
  } catch ( PDOException $e ) {
    print "ERROR: " . $e->getMessage() . "<br />";

    die();
  }
}
// int -> int -> obj
function getPost($threadNum, $postRank) {
  try {
    $db = openDbConn();
    // XXX don't like this, leaves hanging PDOStatement Object
    return $db->query("SELECT post.name, post.datum, post.tid, post.rank, post.date, user.name
                         FROM post
                           LEFT JOIN user
                             ON post.uid = user.uid
                           WHERE post.tid = $threadNum 
                             AND post.rank = $postRank;")->fetch();
  } catch ( PDOException $e ) {
    print "ERROR: " . $e->getMessage() . "<br />";
    die();
  }
}

// int -> int -> obj?
// XXX clean up this uber messy query. Make it quicker mainly.
function getThreads($foraNum, $start, $inc) {
  try {
    $db = openDbConn();
    return $db->query("SELECT
                         thread.id AS id,
                         thread.fid AS fid,
                         thread.mode AS mode,
                           (SELECT inpost.name
                              FROM post AS inpost
                                WHERE post.tid = inpost.tid
                                  AND inpost.rank = (SELECT MIN(post.rank) 
                                                       FROM post AS inpost2 
                                                         WHERE inpost2.tid = inpost.tid)) AS name,
                           (SELECT inpost.datum
                              FROM post AS inpost
                                WHERE post.tid = inpost.tid
                                  AND inpost.rank = (SELECT MIN(post.rank) 
                                                       FROM post AS inpost2 
                                                         WHERE inpost2.tid = inpost.tid)) AS datum,
                         MAX(post.date)
                       FROM thread
                         INNER
                           JOIN post
                             ON post.tid = thread.id
                             WHERE thread.fid = $foraNum
                       GROUP BY thread.id
                       ORDER BY date DESC
                       LIMIT $start,$inc;");
  } catch ( PDOException $e ) {
    print "ERROR: " . $e->getMessage() . "<br />";
    die();
  }
}
// int -> int -> obj?
function getFora( $foraNum, $start, $inc ) {
  try {
    $db = openDbConn();
    return $db->query("SELECT id, name, datum, rank FROM forum
                          WHERE forum.rank 
                          ORDER BY rank LIMIT $start, $inc;");
  } catch ( PDOException $e ) {
    print "ERROR: " . $e->getMessage() . "<br />";
    die();
  }
}

// int -> int -> string -> string -> bool
function setPost( $threadNum, $postNum, $title, $datum, $options ) {
  try {
    $uid = (isset($_SESSION['uid'])) ? $_SESSION['uid'] : 0;
    $mode = (is_string($options['mode'])) ? $db->quote($options['mode']) : "none";
    $time = time();

    $db = openDbConn();

    $title = $db->quote($title);
    $datum = $db->quote($datum);

    $db->beginTransaction();
    // create thread for post -1
    if ( $postNum > 0 ) {  
      $db->exec("UPDATE post 
                                    SET name = $title, 
                                        datum = $datum,
                                        date = $time 
                                    WHERE rank = $postNum
                                      AND tid = $threadNum;");
    } elseif ( $postNum == 0 ) {
      $db->exec("INSERT INTO thread (fid, mode, rank) 
                                    VALUES ( ${threadNum}, $mode, 0 );
                                  INSERT INTO post (tid, uid, rank, name, datum, date) 
                                    VALUES( (SELECT MAX(id) FROM thread), 
                                            $uid,
                                            1 + COALESCE( (SELECT MAX(rank) FROM post
                                                             WHERE tid = (SELECT MAX(id) FROM thread ) ),
                                                      0 ), 
                                            $title, 
                                            $datum,
                                            $time);");
    } elseif ( $postNum < 0 ) {
      $db->exec("INSERT INTO post (tid, uid, rank, name, datum, date) 
                                    VALUES( ${threadNum}, 
                                            $uid,
                                            1+ COALESCE( (SELECT MAX(rank) FROM post
                                                             WHERE tid = (SELECT MAX(id) FROM thread ) ),
                                                      0), 
                                            $title, 
                                            $datum,
                                            $time);");     
    }
    $db->commit();
  } catch ( PDOException $e ) {
    $db->rollback();
    print 'ERROR: ' . $e->getMessage() . '<br />';
    die();
  }
}

// XXX remove the crux of this
// int -> int -> string -> string -> bool
function setThread( $threadNum, $mode ) {
  try {
    $db = openDbConn();
    $mode = $db->quote( $mode );

    $db->beginTransaction();
    $db->exec("UPDATE thread SET mode = $mode WHERE id = $threadNum");
    $db->commit();
  } catch ( PDOException $e ) {
    $db->rollback();
    print "ERROR: " . $e->getMessage() . "<br />";
    die();
  }
}
// int -> int -> string -> string -> bool
// city num as of current is ignored
function setForum( $cityNum, $forumNum, $title, $datum) {
  try {
    $db = openDbConn();

    $title = $db->quote($title);
    $datum = $db->quote($datum);

    $db->beginTransaction();
    ( $forumNum < 1 ) ? $db->exec("INSERT INTO forum (rank, name, datum)
                                      VALUES( 1 + (SELECT MAX(rank) FROM forum),
                                              '$title',
                                              '$datum');")
                      : $db->exec("UPDATE forum
                                     SET datum = '$datum', name = '$title'
                                     WHERE id = $forumNum;");
    $db->commit();
  } catch ( PDOException $e ) {
    $db->rollback();
    print "ERROR: " . $e->getMessage() . "<br />";
    die();
  }
}

function deletePost( $threadNum, $postNum ) {
  try {
    // XXX deleteing all posts will leave hanging thread
    if( postCount($threadNum) < 2 ) {
      // XXX Modify to link post MIN(post.rank) to thread
      die("Please Delete Thread Instead");
    }
    $db = openDbConn();
    $db->beginTransaction();
    $db->exec("DELETE FROM post WHERE post.tid = $threadNum AND post.rank = $postNum;");
    $db->commit();
  } catch ( PDOException $e ) {
    $db->rollback();
    print "ERROR: " . $e->getMessage() . "<br />";
    die();
  }
}
function deleteThread( $forumNum, $threadNum ) {
  try {
    $db = openDbConn();
    $db->beginTransaction();
    $db->exec("DELETE FROM thread WHERE thread.fid = $forumNum AND thread.id = $threadNum");
    $db->exec("DELETE FROM post WHERE post.tid = $threadNum ");
    $db->commit();
  } catch ( PDOException $e ) {
    $db->rollback();
    print "ERROR: " . $e->getMessage() . "<br />";
    die();
  }
}
function deleteForum( $cityNum, $forumNum ) {
  try {
    $db = openDbConn();
    $db->beginTransaction();
    $db->exec("DELETE FROM forum WHERE forum.id = $forumNum");
    $db->exec("DELETE FROM post WHERE post.tid = (SELECT thread.id FROM thread WHERE thread.fid = $forumNum)");
    $db->exec("DELETE FROM thread WHERE thread.fid = $forumNum");
    $db->commit();
  } catch ( PDOException $e ) {
    $db->rollback();
    print "ERROR: " . $e->getMessage() . "<br />";
    die();
  }
}

// int -> int
function postCount($threadNum) {
  try {
    $db = openDbConn();
    // XXX does this work? I don't member
    $res = $db->query("SELECT COUNT(rank) AS pcount FROM post WHERE tid = $threadNum;")->fetch(); 
    $cnt = $res['pcount'];
    $res = NULL;
    return $cnt;
  } catch ( PDOException $e ) {
    print "ERROR: " . $e->getMessage() . "<br />";
    die();
  }
}
// int -> int
function threadCount( $forumNum ) {
  try {
    $db = openDbConn();
    // XXX does this work? I don't member
    $res = $db->query("SELECT COUNT(id) AS tcount FROM thread WHERE fid = $forumNum;")->fetch(); 
    $cnt = $res['tcount'];
    $res = NULL;
    return $cnt;
  } catch ( PDOException $e ) {
    print "ERROR: " . $e->getMessage() . "<br />";
    die();
  }
}


?>

